package edu.yang.dbutils.converter;

import edu.yang.dbutils.TypeConverter;

import java.sql.Time;
import java.sql.Timestamp;
import java.time.*;
import java.util.Date;

/**
 * @author yang
 * @date 2024-05-12
 */
public class DateConverter implements TypeConverter {
    @Override
    public boolean supports(Class<?> fieldType) {
        //获取实体类属性全限定类名
        String typeName = fieldType.getTypeName();
        return switch (typeName){
            case "java.util.Date",
                 "java.sql.Date",
                 "java.sql.Timestamp",
                 "java.sql.Time" -> true;
            default -> false;
        };
    }

    @Override
    public Object convert(Class<?> fieldType, Object value) {
        //获取实体类属性全限定类名
        String typeName = fieldType.getTypeName();
        //将数据库获取的时间类型转换为时间戳格式
        long time = getTime(value);
        return switch (typeName){
            case "java.util.Date" -> new Date(time);
            case "java.sql.Date" -> new java.sql.Date(time);
            case "java.sql.Timestamp" -> new Timestamp(time);
            case "java.sql.Time" -> new Time(time);
            default -> null;
        };
    }

    /**
     * 将任意时间类型对象转换为时间戳
     * @param value
     * @return
     */
    private Long getTime(Object value){
        return switch (value){
            case Date date -> date.getTime();
            case LocalDateTime localDateTime -> localDateTimeToDate(localDateTime).getTime();
            case LocalDate localDate -> localDateToDate(localDate).getTime();
            case LocalTime localTime -> localTimeToDate(localTime).getTime();
            default -> throw new RuntimeException("Unable to convert" + value + "to Date");
        };
    }

    /**
     * LocalDateTime 转为 Date
     * @param localDateTime
     * @return
     */
    private Date localDateTimeToDate(LocalDateTime localDateTime){
        //获取时区ID
        ZoneId zoneId = ZoneId.systemDefault();
        //获取瞬时时间
        Instant instant = localDateTime.atZone(zoneId).toInstant();
        return Date.from(instant);
    }

    /**
     * LocalDate 转为 Date
     * @param localDate
     * @return
     */
    private Date localDateToDate(LocalDate localDate){
        //获取时区ID
        ZoneId zoneId = ZoneId.systemDefault();
        //获取瞬时时间
        Instant instant = localDate.atStartOfDay(zoneId).toInstant();
        return Date.from(instant);
    }

    /**
     * LocalTime 转为 Date
     * @return
     */
    private Date localTimeToDate(LocalTime localTime){
        //获取时区ID
        ZoneId zoneId = ZoneId.systemDefault();
        //获取瞬时时间
        Instant instant = localTime.atDate(LocalDate.now()).atZone(zoneId).toInstant();
        return Date.from(instant);
    }

}
